package ci.web.router;

import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

import java.net.URL;

import ci.web.core.CiContext;

/**
 * 路由中心
 * @author zhh
 */
public class CiRouter implements CiCall{

    private static InternalLogger logger = InternalLoggerFactory.getInstance(CiRouter.class);
    
    private CiFile file;
    //脚本-动态添加类
    private CiHandlerScaner scaner;
    //拦截器
    private CiCall filter;
    
    
    public CiRouter() {
        file = new CiFile("www");
        scaner = new CiHandlerScaner();
    }
    /**
     * 设置静态文件路由
     * @param dir
     * @param path
     * @param maxAge
     */
    public void setFile(String dir, String path, int maxAge){
        file = new CiFile(dir, path, maxAge);
    }
    /**
     * 设置静态文件路由
     * @param f
     */
    public void setFile(CiFile f){
        if(f!=null){
            file = f;
        }
    }
    /**
     * 获取静态文件路由
     * @return
     */
    public CiFile getFile(){
        return file;
    }
    
    /**
     * 获取filter
     * @return
     */
    public CiCall getFilter(){
        return filter;
    }
    /**
     * 设置filter
     * @param r
     */
    public void setFilter(CiCall r){
        filter = r;
    }
    
    /**
     * 设置脚本扫描器
     * @param dir           扫描路径
     * @param packageName   扫描限定包
     */
    public void setHandler(String dir, String packageName){
        scaner = new CiHandlerScaner(dir, packageName, scaner.handlers());
    }
    /**
     * 获取脚本扫描器
     * @return
     */
    public CiHandlerScaner getHandler(){
        return scaner;
    }
    
    /**
     * 直接添加脚本实现类
     * @param clazz
     */
    public void add(Class<?> clazz){
        scaner.add(clazz);
    }
    
    /**
     * call
     * @param ctx
     * @return
     * @throws Exception
     */
    public boolean call(CiContext ctx) throws Exception{
        return this.call(ctx, scaner.loader());
    }
    
    public boolean call(CiContext ctx, ClassLoader loader) throws Exception{
        try{
            if(filter!=null && filter.call(ctx, loader)){
                return true;
            }
            if(file.match(ctx)){
                return file.call(ctx, loader);
            }
            CiHandler wrap = scaner.get(ctx);
            if(wrap!=null){
                return wrap.call(ctx, loader);
            }
        }catch(Exception e){
            ctx.out().setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);
            logger.error("call", e);
            return true;
        }
        return false;
    }
    /**
     * 脚本扫描路径URL
     * @return
     */
    public URL[] urls(){
        return scaner.urls();
    }
    /**
     * 重新扫描脚本
     */
    public synchronized void reload() {
       this.scaner = new CiHandlerScaner(scaner.dir(), scaner.packageName(), scaner.handlers());
    }
    
}
